import java.util.*;

public class Request {
	private Date _dbVersion = null;					// since which date update is required 
	private ArrayList<String> _arrivedArr = null;	// holds the entries that were arrived 
	private int _entriesExpected;					// number of entries expected
	private int _entriesArrived;					// number of entries that were arrived 
	public Date _destinationDbVersion = null;		// destination DB version
	public Message _request = null;					// request entry message
	
	/**
	 * Constructor
	 * @param dbVersion
	 * @param destinationDbVer
	 * @param request
	 */
	public Request(Date dbVersion, Date destinationDbVer, Message request){
		_dbVersion = dbVersion;
		_arrivedArr = null;
		_entriesExpected = -1;
		_entriesArrived = 0;
		_request = request;
		_destinationDbVersion = destinationDbVer;
	}
	
	/**
	 * equals function
	 */
	@Override
	public boolean equals(Object o){
		if (!(o instanceof Request))
			return false;
		
		Request req = (Request) o;
		return _dbVersion.equals(req._dbVersion);
	}
	
	/**
	 * hashCode
	 */
	@Override
	public int hashCode(){
		return _dbVersion.hashCode();
	}
	
	/**
	 * @return number of entries expected
	 */
	public synchronized int getEntriesExpected(){ return _entriesExpected; }
	
	/**
	 * Sets the number of expected entries.
	 * @param entriesExpected
	 */
	public synchronized void setEntriesExpected(int entriesExpected) {
		_entriesExpected = entriesExpected;
		_arrivedArr = new ArrayList<String>(entriesExpected + 1);
		for (int i = 0; i < entriesExpected + 1; ++i)
			_arrivedArr.add("-1");
	}
	
	/**
	 * Set the relevant cell in the arrived entries array, according to the entry serial number,
	 * with the name of the peer that was arrived. 
	 * @param entrySN
	 * @param peerName
	 */
	public synchronized void setBit(int entrySN, String peerName){
		if (!_arrivedArr.contains(peerName)){
			_arrivedArr.add(entrySN, peerName);
			++_entriesArrived;
		}
	}
	
	/**
	 * Check if entry was arrived
	 * @param entrySn
	 * @return - The peer name of the entry.
	 */
	public synchronized String wasArrived(int entrySn){ return _arrivedArr.get(entrySn); }
	
	// get functions //
	public int getEntriesArrived(){ return _entriesArrived; }
	
	public Date getDbVersion(){ return _dbVersion; }
	
	public Date getDestinationDbVer() { return _destinationDbVersion; }
	
	public Message getRequest(){ return _request; }
	
	// set functions //
	public void setDbVersion(Date dbVersion) { _dbVersion = dbVersion; }
		
	public void setDestinationDbVer(Date destinationDbVer) {
		if (destinationDbVer.compareTo(_destinationDbVersion) == 1)
			_destinationDbVersion = destinationDbVer;
	}
	
	/**
	 * compareTo Function
	 * @param req
	 * @return
	 */
	public int compareTo(Request req){ return _dbVersion.compareTo(req.getDbVersion()); }
	
}
